package com.wxzhou.wangzhuan.api;

import com.wxzhou.wangzhuan.dto.*;
import com.wxzhou.wangzhuan.exception.AdReportException;
import com.wxzhou.wangzhuan.security.UserContext;
import com.wxzhou.wangzhuan.service.AdService;
import com.wxzhou.wangzhuan.util.AdvancedGsonPrettyPrint;
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.jboss.logging.Logger;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 广告api上报
 */
@Path("/api/ad")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class AdApi {
    private static final Logger LOG = Logger.getLogger(AdApi.class);

    @Inject
    AdService adService;

    @Inject
    UserContext userContext;


    /**
     * 广告上报
     *
     * @param adReportInfo
     * @return
     */
    @POST
    @Path("/report")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<Response> adReport(@Valid List<AdReportInfo> adReportInfo) {
//        LOG.debug(AdvancedGsonPrettyPrint.prettyPrint(adReportInfo));
        boolean authenticated = userContext.isAuthenticated();
        if (!authenticated) {
            ResponseDto<Object> unauthorized = ResponseDto.unauthorized("");
            return Uni.createFrom().item(Response.status(unauthorized.getCode()).entity(unauthorized).build());
        }
        return adService.reportAd(adReportInfo, userContext.getCurrentUserInfo())
                .onItem().transform(response -> {
                    if (response != null) {
                        ResponseDto<AdReportResponse> resp = ResponseDto.success(response);
                        return Response.ok(resp).build();
                    } else {
                        ResponseDto<Map<String, Object>> resp = ResponseDto.fail("拉取频率过快，等会再拉取");
                        return Response.status(500).entity(resp).build();
                    }
                })
                .onFailure().recoverWithUni(throwable -> {
                    String msg = "";
                    if (throwable instanceof AdReportException) {
                        msg = throwable.getMessage();
                        LOG.errorf("广告上报失败: " + throwable.getMessage());
                    }else if( throwable.getCause() instanceof AdReportException){
                        msg = throwable.getCause().getMessage();
                        LOG.errorf(throwable, "广告上报失败: " + throwable.getCause().getMessage());
                    }else{
                        LOG.errorf(throwable, "广告上报失败: " + throwable.getMessage());
                    }
                    LOG.errorf(throwable, "广告上报失败: " + throwable.getMessage());
                    ResponseDto<Map<String, Object>> resp = ResponseDto.error("广告上报失败: " + msg);
                    return Uni.createFrom().item(Response.status(500).entity(resp).build());

                });
    }

    /**
     * 预请求广告，表明要拉广告之前的请求
     *
     * @param adPreReportInfo
     * @return
     */
    @POST
    @Path("/pre-report")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<Response> preReport(@Valid AdPreReportInfo adPreReportInfo) {

        Optional<UserInfoDto> currentUserInfo = userContext.getCurrentUserInfo();

        return adService.preReportAd(adPreReportInfo, currentUserInfo).onItem().transform(response -> {
            if (response != null) {
                ResponseDto<AdPreReportResponse> resp = ResponseDto.success(response);
                return Response.ok(resp).build();
            } else {
                ResponseDto<Map<String, Object>> resp = ResponseDto.fail("拉取频率过快，等会再拉取");
                return Response.status(500).entity(resp).build();
            }
        }).onFailure().recoverWithUni(throwable -> {
            String msg = "";
            if (throwable instanceof AdReportException) {
                msg = throwable.getMessage();
                LOG.errorf("广告预拉失败: " + throwable.getMessage());
            }else{
                LOG.errorf(throwable, "广告预拉失败: " + throwable.getMessage());
            }
            ResponseDto<Map<String, Object>> resp = ResponseDto.error("预拉失败: " + msg);
            return Uni.createFrom().item(Response.status(500).entity(resp).build());
        });
    }

}
